﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.ComponentModel;
using System.Diagnostics;

namespace MyWcfRestClient
{
    public class ViewModelBase : DependencyObject, INotifyPropertyChanged
    {
        public ViewModelBase()
        {
            Debug.Assert(Application.Current.Dispatcher.CheckAccess(), "All ViewModels must be created in Main thread!");
        }

        #region Properties

        #endregion

        #region INotifyPropertyChanged implementation

        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Raise the property changed event for the given property.
        /// </summary>
        /// <param name="propertyName">The name of the property that has changed.</param>
        protected void ReportPropertyChanged(string propertyName)
        {
            ReportPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }

        /// <summary>
        /// Raise the property changed event for the given property.
        /// </summary>
        protected void ReportPropertyChanged(PropertyChangedEventArgs e)
        {
            PropertyChangedEventHandler propertyChanged = PropertyChanged;

            if (propertyChanged != null)
            {
                // Raise the event for the given property.
                propertyChanged(this, e);
            }
        }


        /// <summary>
        /// Raise the property changed event for exactly the given properties
        /// </summary>
        protected void ReportPropertyChanged(params string[] propertyNames)
        {
            if (propertyNames == null)
                throw new ArgumentNullException("propertyNames");

            Debug.Assert(propertyNames.Length > 0, "Calling ReportPropertyChanged without parameter does not have any effect!");

            PropertyChangedEventHandler propertyChanged = PropertyChanged;

            if (propertyChanged != null)
            {
                foreach (var propertyName in propertyNames)
                {
                    Debug.Assert(TypeDescriptor.GetProperties(this).Find(propertyName, false) != null, "Raising event for unknown property " + propertyName);
                    propertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }

        /// <summary>
        /// Raise the property changed event for all public properties
        /// </summary>
        protected void ReportAllPropertiesChanged()
        {
            PropertyChangedEventHandler propertyChanged = PropertyChanged;

            if (propertyChanged != null)
            {
                foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(this))
                {
                    propertyChanged(this, new PropertyChangedEventArgs(property.Name));
                }
            }

        }

        #endregion

    }
}
